package pcloud.client.watcher;

import java.lang.Thread.State;

import pcloud.client.scheduler.TaskScheduler;
import pcloud.client.util.FileResourceInfo;
import pcloud.client.util.GlobalConfig;
import pcloud.client.util.TreeDB;
import pcloud.client.util.Logger;
import pcloud.client.util.Tree;

public class PollClientWatcher implements ClientWatcher, Runnable
{
    private TaskScheduler taskScheduler;
	private volatile boolean watcherOn;
	private Thread watcherThread;
	private TreeDB<FileResourceInfo> localDB;

	public PollClientWatcher(TaskScheduler taskScheduler)
	{
        this.taskScheduler = taskScheduler;
	}

	public PollClientWatcher(TaskScheduler taskScheduler, TreeDB<FileResourceInfo> localDB)
	{
        this.taskScheduler = taskScheduler;
        this.localDB = localDB;
	}


	public Thread getWorkingThread()
	{
		return watcherThread;
	}

	@Override
	public void start()
	{
		watcherThread = new Thread(this);
		watcherOn = true;
		State state = watcherThread.getState();
		logger.info("PollClientWatcher starting, current state: " + state);

		if (state.equals(State.TERMINATED) || state.equals(State.NEW)) {
			watcherThread.start();
		}
	}

	@Override
	public void stop()
	{
		watcherOn = false;
	}

	private void traverseOnce()
	{
		String[] localFolders = GlobalConfig.getInstance().getLocalFolders();
		for (String watchFolder : localFolders)
		{
			PollClientWatcherNode rootNode = new PollClientWatcherNode(this, watchFolder, watchFolder);
			rootNode.initialize();
			logger.info("traverseOnce, rootNode= ["+ watchFolder+"]");
			Tree.traverse(rootNode);
		}
	}
	
	public void syncOnce()
	{
		traverseOnce();
	}

	@Override
	public void run()
	{
		logger.info("PollClientWatcher thread started!");
		while (watcherOn) {
			try {
				traverseOnce();
				Thread.sleep(300000);
			} catch (Exception e) {
				logger.info("PollClientWatcher exception!"+e.getMessage());
			}
		}
		logger.info("PollClientWatcher thread ended!");
	}

	@Override
	public void setLocalDB(TreeDB<FileResourceInfo> localDB)
	{
		this.localDB = localDB;
	}

	public TreeDB<FileResourceInfo> getLocalDB()
	{
		return localDB;
	}
	
	public TaskScheduler getScheduler()
	{
		return taskScheduler;
	}
	
}
